'''
Definition of the table contributors and charity_payments recording the
contributors and their payments.

@author: Pierre Thibault (pierre.thibault1 -at- gmail.com)
@organization: Voice of Access (http://voiceofaccess.org)
@license: MIT
@since: 2010-10-20
'''

__docformat__ = "epytext en"

# Static analyzer import helpers:
if 0: 
    None
    import gluon
#    from gluon.contrib.gql import GQLDB
#    from gluon.html import A
#    from gluon.html import B
#    from gluon.html import BEAUTIFY
#    from gluon.html import BODY
#    from gluon.html import BR
#    from gluon.html import CENTER
#    from gluon.html import CLEANUP 
#    from gluon.html import CODE
#    from gluon.html import CRYPT
#    from gluon.html import DIV
#    from gluon.html import FORM
#    from gluon.html import I
#    from gluon.html import IFRAME
#    from gluon.html import IMG
#    from gluon.html import INPUT
#    from gluon.html import IS_ALPHANUMERIC
#    from gluon.html import IS_DATETIME
#    from gluon.html import IS_DATETIME
#    from gluon.html import IS_DATETIME_IN_RANGE
#    from gluon.html import IS_DATE_IN_RANGE
    from gluon.html import IS_DECIMAL_IN_RANGE
    from gluon.html import IS_EMAIL
#    from gluon.html import IS_EMPTY_OR
#    from gluon.html import IS_EQUAL_TO
#    from gluon.html import IS_EXPR
#    from gluon.html import IS_FLOAT_IN_RANGE
#    from gluon.html import IS_IMAGE
#    from gluon.html import IS_INT_IN_RANGE
    from gluon.html import IS_IN_DB
    from gluon.html import IS_IN_SET
#    from gluon.html import IS_IPV4
#    from gluon.html import IS_LENGTH
#    from gluon.html import IS_LIST_OF
#    from gluon.html import IS_LOWER
#    from gluon.html import IS_MATCH
#    from gluon.html import IS_NOT_EMPTY
    from gluon.html import IS_NOT_IN_DB
#    from gluon.html import IS_NULL_OR
#    from gluon.html import IS_SLUG
#    from gluon.html import IS_STRONG 
#    from gluon.html import IS_TIME
#    from gluon.html import IS_UPLOAD_FILENAME
#    from gluon.html import IS_UPPER
#    from gluon.html import IS_URL
#    from gluon.html import LABEL
#    from gluon.html import LEGEND
#    from gluon.html import LI
#    from gluon.html import LINK
#    from gluon.html import MARKMIN
#    from gluon.html import MENU
#    from gluon.html import META
#    from gluon.html import OBJECT
#    from gluon.html import OL
#    from gluon.html import ON
#    from gluon.html import OPTGROUP
#    from gluon.html import OPTION
#    from gluon.html import P
#    from gluon.html import PRE
#    from gluon.html import SCRIPT
#    from gluon.html import SELECT
#    from gluon.html import SPAN
#    from gluon.html import TABLE
#    from gluon.html import TAG
#    from gluon.html import TBODY
#    from gluon.html import TD
#    from gluon.html import TEXTAREA
#    from gluon.html import TFOOT
#    from gluon.html import TH 
#    from gluon.html import THEAD
#    from gluon.html import TITLE
#    from gluon.html import TR
#    from gluon.html import TT
#    from gluon.html import UL
#    from gluon.html import URL
#    from gluon.html import XHTML
#    from gluon.html import XML
#    from gluon.html import embed64
#    from gluon.html import xmlescape
#    from gluon.sql import SQLDB
    from gluon.sqlhtml import SQLFORM
#    from gluon.sql import SQLField
#    from gluon.sqlhtml import SQLTABLE
#    from gluon.html import STYLE
#    from gluon.http import redirect
    import gluon.languages.translator as T
#    from gluon.tools import  Auth
#    from gluon.tools import Service
    global auth; auth = gluon.tools.Auth()
#    global cache; cache = gluon.cache.Cache()
#    global crud; crud = gluon.tools.Crud()
    global db; db = gluon.sql.DAL()
#    import gluon.compileapp.local_import_aux as local_import
    global request; request = gluon.globals.Request()
#    global response; response = gluon.globals.Response()
#    global service; service = gluon.tools.Service()
#    global session; session = gluon.globals.Session()
#    global DAL; DAL = gluon.dal()
#    global HTTP; HTTP = gluon.http()
#    global LOAD; LOAD = gluon.compileapp.LoadFactory()

from gluon.tools import Field

global DEBUG
if DEBUG:
    # Relaod the module to get the changes:
    import uc_web2py_utils.i18n
    uc_web2py_utils.i18n = reload(uc_web2py_utils.i18n)
    import uc_web2py_utils.helpers
    uc_web2py_utils.helpers = reload(uc_web2py_utils.helpers)
from uc_web2py_utils.i18n import fr_en_language_set
from uc_web2py_utils.i18n import format_phone
from uc_web2py_utils.i18n import format_postal_code
from uc_web2py_utils.i18n import translate
from uc_web2py_utils.helpers import Web2pyEnum

# from _db.py:
if 0:
    # Set the default default for the table contributors:
    DEFAULT_LANGUAGE = None
    DEFAULT_CITY = None
    DEFAULT_STATE = None
    DEFAULT_COUNTRY = None 
    
    # Set common field size:
    LANGUAGE_SIZE = None
    CITY_SIZE = None
    STATE_SIZE = None
    COUNTRY_SIZE = None


#----------------------------------------------------------------------------- 
# contributors table
#----------------------------------------------------------------------------- 

# Set the default to use for this request:
if auth.is_logged_in():
    default_language = auth.user.default_language
    default_city = auth.user.default_city
    default_state = auth.user.default_state
    default_country = auth.user.default_country
else:
    default_language = DEFAULT_LANGUAGE
    default_city = DEFAULT_CITY
    default_state = DEFAULT_STATE
    default_country = DEFAULT_COUNTRY 
default_city = translate(default_city, default_language, T)
default_state = translate(default_state, default_language, T)
default_country = translate(default_country, default_language, T)

def format_address(r):
    """
    Compute the full address for the contributors table.
    Example of an address:
        Madame Germaine Morisset
        Directrice du service de publicité
        Les Éditions du Hibou
        Bureau 102, tour Est
        3974, boulevard Saint-Laurent
        Montréal (Québec)  H2W 1Y3
    """
    return \
        r.full_name + "\n" + \
        r.address + "\n" + \
        r.city + " (" + r.state + ")  " + "r.postal_code" + "\n"

def format_contributor(r):
    """
    Format of a contributor for display.
    """
    return r.full_name + ", " + \
            r.email + ", " + \
            r.city + " (" + r.state + ")"
            
db.define_table(
    "contributors",
    Field('canvasser', db.auth_user, default=auth.user_id, 
          requires=IS_IN_DB(db, db.auth_user.id), label=T("Canvasser")),
    Field('full_name', length=50, default="", required=True, 
          notnull=True, label=T("Name")),
    Field('language', length=LANGUAGE_SIZE, default=default_language, 
          required=True, 
          requires=IS_IN_SET(fr_en_language_set(T), zero=None),
          notnull=True,
          label=T("Favorite language")),
    Field('address', "text", length=255, default=None, 
          label=T("Address")),
    Field('city', length=CITY_SIZE, default=default_city, label=T("City")),
    Field('state', length=STATE_SIZE, default=default_state, 
          label=T("Province/State")),
    Field('country', length=COUNTRY_SIZE, default=default_country,
          label=T("Country")),
    #TODO: Add javascript formatting for postal code
    Field('postal_code', length=8, default=None, label=T("Postal Code"),
          comment=T("Type as you like. Only letters and numbers matter."),
          represent=format_postal_code),
    Field('full_address', length=500, default=None, label=T("Full address"),
          compute=format_address),
    Field('email', length=128, default=None,
          unique=True, label=T("Email")),
    #TODO: Add javascript formatting for phones
    Field('telephone_home', length=10, default=None, 
          label=T("Telephone Home"), 
          comment=T("Type as you like. Only numbers matter."),
          represent=format_phone),
    Field('telephone_work', length=10, default=None, 
          label=T("Telephone Work"),
          comment=T("Type as you like. Only numbers matter."),
          represent=format_phone),
    Field('date_time', "datetime", default=request.now, 
          label=T("Date and time")),
    format=format_contributor)
db.contributors.email.requires = \
    (IS_EMAIL(), IS_NOT_IN_DB(db, db.contributors.email))
#----------------------------------------------------------------------------- 
# contribution table
#----------------------------------------------------------------------------- 

def format_card_number(r):
    card_number = r.card_number
    if len(card_number) == 16:
        return " ".join(card_number[:4], card_number[4:8], card_number[8:12], 
                card_number[:-4])
    
class FrequencyEnum(Web2pyEnum):
    ONE_TIME = "OneTime"
    MONTHLY = "Monthly"
    ENUM_VALUES = (ONE_TIME, MONTHLY)
    
class FundTypeEnum(Web2pyEnum):
    ANNUAL_FUND = "Annual Fund"
    FINANCIAL_AID = "Financial Aid"
    OTHER = "Other"
    ENUM_VALUES = (ANNUAL_FUND, FINANCIAL_AID, OTHER)
    
class PaymentTypeEnum(Web2pyEnum):
    CREDIT_CARD = "Credit Card" 
    ELECTRONIC_CHECK = "Electronic Check" 
    ENUM_VALUES = (CREDIT_CARD, ELECTRONIC_CHECK)
    
# Start date must be the future for new records
db.define_table(
    'contributions',
    Field('contributor', db.contributors, 
          requires=IS_IN_DB(db, db.contributors.id), label=T("Contributor")),
    Field('canvasser', db.auth_user, default=auth.user_id, 
          requires=IS_IN_DB(db, db.auth_user.id), label=T("Canvasser")),
    Field('amount', "decimal(9,2)", default=0, required=True,
          requires=IS_DECIMAL_IN_RANGE(0, 1e10-1), notnull=True, 
          label=T("Amount"), ),
    Field("start_date", "date", default=request.now, required=True,
          label=T("Payment Start Date")),
    Field('frequency', length=10, default=FrequencyEnum.ONE_TIME,
          requires=FrequencyEnum.IS_IN_SET(T, IS_IN_SET),
          widget=SQLFORM.widgets.radio.widget, label=T("Frequency")),
    Field("fund_type", length=20, default=FundTypeEnum.ANNUAL_FUND,
          requires=FundTypeEnum.IS_IN_SET(T, IS_IN_SET), 
          widget=SQLFORM.widgets.radio.widget, label=T("Type of Fund")),
    Field("payment_type", length=20, default=PaymentTypeEnum.CREDIT_CARD,
          requires=PaymentTypeEnum.IS_IN_SET(T, IS_IN_SET),
          widget=SQLFORM.widgets.radio.widget, label=T("Payment Type")),
    Field("card_number", 'string', length=20, default=None,
          required=False, unique=True,label=T("Card Number"),
          represent=format_card_number),
    Field('date_time', "datetime", default=request.now, 
          label=T("Date and time")),
    format=lambda r:T("%(amount).2F %(frequency)s", 
                      dict(amount=r.amount, frequency=T(r.frequency))))
